package com.C1对象及变量的并发访问.S1synchronized同步方法.S3synchronized方法与对象锁.A脏读;

/**
 * @Auther: SJZ    2907374717@qq.com
 * @Date: 2019/3/14 21:24
 * @Description:
 *
 * dirtyread：脏读
 * 实现多个线程调用同一个方法时，为了避免数据出现交叉的情况，使用synchronized关键字来进行同步。
 * 虽然在赋值是进行了同步，但在取值时有可能出现一些意思不到的意外，这种情况这种情况就是脏读，发生
 * 脏读的情况是在读取实例变量时，此值已经被其他线程更改过了。
 * 下面出现脏读，是因为public void getValue()方法并不是同步的，所以可以在任意时候进行调用。解决
 * 办法当然就是加上synchronized关键字.
 */
public class DirtyReadTest {

    public String username="A";
    public String password="AA";
    synchronized public void setValue(String username,String password){
        try{
            this.username=username;
            Thread.sleep(5000);
            this.password=password;
            System.out.println("setValue method thread name"
            +Thread.currentThread().getName()+"username"+username+" password="+password);
        }catch(InterruptedException e){
           e.printStackTrace();
        }
    }


    public  void getVlaue(){
        System.out.println("get method thread name="+Thread.currentThread().getName()+" username="+
        username+" password="+password);
    }


    public static void main(String[] args) throws InterruptedException {
        DirtyReadTest dirtyReadTest=new DirtyReadTest();
        ThreadA threadA=new ThreadA(dirtyReadTest);
        threadA.start();
        threadA.sleep(200);//打印结果受此值大小影响。
        dirtyReadTest.getVlaue();
    }

    static class ThreadA extends Thread{
        private DirtyReadTest dirtyReadTest;
        public ThreadA(DirtyReadTest dirtyReadTest){
            super();
            this.dirtyReadTest=dirtyReadTest;
        }
        public  void run(){
            super.run();
            dirtyReadTest.setValue("B","BB");
        }
    }

}
